import { Component, Injector, ViewChild } from '@angular/core';
import { AppComponentBase } from '@shared/common/app-component-base';
import { IEntityDtoOfGuid, NameValueDto  } from '@shared/service-proxies/service-proxies';
import { BsModalRef } from 'ngx-bootstrap/modal';
import { merge as _merge } from 'lodash-es';
import { Paginator } from 'primeng/paginator';
import { Table } from 'primeng/table';
import { finalize } from 'rxjs/operators';
import { map as _map } from 'lodash-es';
import { LazyLoadEvent } from 'primeng/api';
import { Observable } from 'rxjs';
import { DateTime } from 'luxon';

export interface IManualSyncModalOptions {
    defaultParam: any;
    getDataFunc: (paras: any) => Observable<any>;
    getItems: (result: any) => ManualSyncListData[];
    confirmFunc: (paras: any) => Observable<any>;
    confirmDefaultParam: any;
    keyList:NameValueDto[];
}

class ManualSyncListData {
    id: string;
    title: string;
    creationTime: DateTime;
    lastModificationTime: DateTime;
}

@Component({
    templateUrl: './manual-sync-modal.component.html'
})
export class ManualSyncModalComponent extends AppComponentBase {

    @ViewChild('dataTable', { static: true }) dataTable: Table;
    @ViewChild('paginator', { static: true }) paginator: Paginator;

    options: IManualSyncModalOptions;

    filterText = '';

    selectedDatas: IEntityDtoOfGuid[];

    callback: {():void};

    saving: boolean = false;

    selectedKey: string = '';
    keyList: NameValueDto[] = [];

    synchorizationInfo:any ={};

    private hasModified = false;

    constructor(
        injector: Injector,
        public bsModalRef: BsModalRef
    ) {
        super(injector);
    }

    close(): void {
        if(this.hasModified && this.callback){
            this.callback();
        }

        this.bsModalRef.hide();
    }

    configure(options: IManualSyncModalOptions): void {
        this.options = options;

        if(this.options.keyList){
            this.keyList = this.options.keyList;
        }

        if(this.keyList.length > 0){
            this.selectedKey =  this.keyList[0].value;
       }
    }

    shown(): void {
       this.getListData(null);
    }

    getListData(event?: LazyLoadEvent){
        if (this.primengTableHelper.shouldResetPaging(event)) {
            if (this.primengTableHelper.TryChangePage(this.paginator, 0)) {
              return;
            }
          }
          this.selectedDatas = [];
          this.primengTableHelper.showLoadingIndicator();

          let input = this.options.defaultParam;
          input.alias = this.selectedKey;
          input.filter = this.filterText;
          input.sorting = this.primengTableHelper.getSorting(this.dataTable);
          input.maxResultCount = this.primengTableHelper.getMaxResultCount(this.paginator, event);
          input.skipCount = this.primengTableHelper.getSkipCount(this.paginator, event);

          this.options.getDataFunc(input)
          .pipe(finalize(() => this.primengTableHelper.hideLoadingIndicator()))
          .subscribe(result => {
            this.primengTableHelper.totalRecordsCount = result.totalCount;
            this.primengTableHelper.records = this.options.getItems(result.items);
            this.primengTableHelper.hideLoadingIndicator();
          });
    }

    getSelectedIds() {
        return _map(this.selectedDatas, selectedMember => selectedMember.id);
    }

    confirm() {
        if (this.saving) {
            return;
        }

        this.synchorizationInfo.isBeginRequest = false;
        this.synchorizationInfo.currentIndex = 0;
        this.synchorizationInfo.allNums = 0;

        var list = this.getSelectedIds();
        if (list.length == 0) {
            return;
        }

        this.synchorizationInfo.isBeginRequest = true;
        this.synchorizationInfo.allNums = list.length;
        this.submit(0, list);
        this.selectedDatas = [];
        this.hasModified = true;
    };

    private submit(index, data) {
        this.saving = true;

        this.synchorizationInfo.currentIndex = index + 1;
        this.synchorizationInfo.currentId = data[index];
        
        let input = this.options.confirmDefaultParam;
        input.id = data[index];
        this.options.confirmFunc(input)
        .pipe(finalize(() => {if(index + 1 === data.length){this.saving = false}}))
        .subscribe(result =>{
            if (result.syncResult) {
                if (index + 1 < data.length) {
                    index += 1;
                    this.submit(index, data);
                }
                else {
                    this.notify.success(this.l('ManualSynchorizationSuccessfully'));
                    this.synchorizationInfo.isBeginRequest = false;
                    this.synchorizationInfo.currentIndex = 0;
                    this.synchorizationInfo.allNums = 0;
                    this.saving = false;
                }
            }else{
                this.notify.warn(this.l('ManualSynchorizationFail'));
            }
        });
    }
}
